package ar.edu.itba.it.cg.grupo01.game.terrain;

import java.util.ArrayList;
import java.util.Properties;

import ar.edu.itba.it.cg.grupo01.game.terrain.proctextures.ProceduralTextureFactory;
import ar.edu.itba.it.cg.grupo01.utils.Utils;

import com.jme.bounding.BoundingBox;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.StaticPhysicsNode;

public class Obstacles extends Node {

	private static final long serialVersionUID = 1L;
	private PhysicsSpace physicsSpace;
	private Properties properties;

	public Obstacles(PhysicsSpace physicsSpace, Properties properties) {
		this.properties = properties;
		this.physicsSpace = physicsSpace;
		createBoxObstacles();
		createBridges();
	}

	private void createBoxObstacles() {
		ArrayList<Vector3f> positions = parsePositions("box");

		float mass = Float.valueOf(properties.getProperty("box.mass"));
		ProceduralTextureFactory ptf = ProceduralTextureFactory
				.valueOf(properties.getProperty("box.pt"));
		
		for (Vector3f v : positions) {
			createBoxObtacle(v.x, v.y, v.z, 0, null, physicsSpace, ptf, mass);
		}

	}

	private void createBridges() {
		ArrayList<Vector3f> positions = parsePositions("bridge");

		int i = 1;
		Vector3f bridgeProps;

		ProceduralTextureFactory ptf = ProceduralTextureFactory
		.valueOf(properties.getProperty("bridge.pt"));

		for (Vector3f v : positions) {
			bridgeProps = parseBridgeProperties(i++);
			createRamp(v.x, v.y, v.z, bridgeProps.x, Vector3f.UNIT_Z,
					bridgeProps.y, bridgeProps.z, ptf);
		}
	}

	private Vector3f parseBridgeProperties(int i) {
		return Utils
				.getPosition(properties.getProperty("bridge" + i + ".prop"));
	}

	private ArrayList<Vector3f> parsePositions(String toParse) {

		int amount = Integer.valueOf(properties
				.getProperty(toParse + ".amount"));

		ArrayList<Vector3f> resultPos = new ArrayList<Vector3f>();
		for (int i = 1; i <= amount; i++) {

			resultPos.add(Utils.getPosition(properties.getProperty(toParse + i
					+ ".pos")));
		}

		return resultPos;
	}

	private void createRamp(float x, float y, float z, float angle,
			Vector3f axis, float sx, float sz, ProceduralTextureFactory pt) {
		final StaticPhysicsNode node = physicsSpace.createStaticNode();
		final Box box = new Box("ramp", new Vector3f(), sx, 3f, sz);
		node.attachChild(box);
		box.setModelBound(new BoundingBox());

		box.updateModelBound();
		box.setRenderState(pt.getTexture().getTextureState());
		box.updateModelBound();
		node.generatePhysicsGeometry();
		node.getLocalRotation().fromAngleNormalAxis(angle, axis);
		node.getLocalTranslation().set(x, y, z);
		node.setIsCollidable(false);
		
		this.attachChild(node);
	}

	private void createBoxObtacle(float x, float y, float z, float angle,
			Vector3f axis, PhysicsSpace physicsSpace,
			ProceduralTextureFactory pt, float mass) {

		Spatial geom = new Box("", new Vector3f(), 5, 5, 5);
		geom.setRenderState(pt.getTexture().getTextureState());

		final DynamicPhysicsNode node = physicsSpace.createDynamicNode();
		node.attachChild(geom);
		node.generatePhysicsGeometry();
		geom.setModelBound(new BoundingBox());
		geom.updateModelBound();
		if (axis != null) {
			node.getLocalRotation().fromAngleNormalAxis(angle, axis);
		}
		node.getLocalTranslation().set(x, y, z);
		node.setMass(mass);
		node.rest();
		this.attachChild(node);
	}

}
